---
title: Email Providers
---

import { useState } from "react"
import { RichTabs } from "@/components/RichTabs"

import { Callout, Steps, Tabs } from "nextra/components"
import { Code } from "@/components/Code"
import { Link } from "@/components/Link"
import { Screenshot } from "@/components/Screenshot"
import MagicLink from "../../../public/img/magic-links/start.webp"

# Email Provider

This login mechanism starts by the user providing their email address at the login form. Then a **Verification Token** is sent to the provided email address. The user then has 24 hours to click the link in the email body to "consume" that token and register their account, otherwise the verification token will expire and they will have to request a new one.

<Callout>
  An Email Provider can be used with both [JSON Web Tokens](https://jwt.io/) and
  [database](/concepts/session-strategies#database-session) session, whichever
  you choose, you **must still configure a database** so that Auth.js can save
  the verification tokens and look them up when the user attempts to login. It
  is not possible to enable an email provider without using a database.
</Callout>

### Providers

<div className="flex flex-col w-full gap-6 items-start">
  <RichTabs
    orientation="horizontal"
    tabKey="Resend"
    defaultValue="resend"
    className="w-full flex flex-col"
  >
    <RichTabs.List className="grid grid-cols-[repeat(auto-fit,140px)] justify-center gap-4">
      <RichTabs.Trigger
        value="forwardemail"
        orientation="vertical"
        className="!border border-neutral-200 dark:border-neutral-700 aria-selected:!bg-neutral-100 aria-selected:dark:!bg-neutral-950 dark:!bg-neutral-900 !bg-white !h-auto !w-auto !gap-2 !justify-start p-6 px-8 rounded-md outline-none transition-all duration-300 hover:bg-neutral-200 !font-normal"
      >
        <img className="size-16 dark:bg-[currentColor]" src={`/img/providers/forwardemail.svg`} />
        <div className="text-sm text-center line-clamp-1">Forward Email</div>
      </RichTabs.Trigger>
      <RichTabs.Trigger
        value="resend"
        orientation="vertical"
        className="!border border-neutral-200 dark:border-neutral-700 aria-selected:!bg-neutral-100 aria-selected:dark:!bg-neutral-950 dark:!bg-neutral-900 !bg-white !h-auto !w-auto !gap-2 !justify-start p-6 px-8 rounded-md outline-none transition-all duration-300 hover:bg-neutral-200 !font-normal"
      >
        <img className="size-16 dark:bg-[currentColor]" src={`/img/providers/resend.svg`} />
        <div className="text-sm text-center">Resend</div>
      </RichTabs.Trigger>
      <RichTabs.Trigger
        value="sendgrid"
        orientation="vertical"
        className="!border border-neutral-200 dark:border-neutral-700 aria-selected:!bg-neutral-100 aria-selected:dark:!bg-neutral-950 dark:!bg-neutral-900 !bg-white !h-auto !w-auto !gap-2 !justify-start p-6 px-8 rounded-md outline-none transition-all duration-300 hover:bg-neutral-200 !font-normal"
      >
        <img className="size-16" src={`/img/providers/sendgrid.svg`} />
        <div className="text-sm text-center">Sendgrid</div>
      </RichTabs.Trigger>
      <RichTabs.Trigger
        value="nodemailer"
        orientation="vertical"
        className="!border border-neutral-200 dark:border-neutral-700 aria-selected:!bg-neutral-100 aria-selected:dark:!bg-neutral-950 dark:!bg-neutral-900 !bg-white !h-auto !w-auto !gap-2 !justify-start p-6 px-8 rounded-md outline-none transition-all duration-300 hover:bg-neutral-200 !font-normal"
      >
        <img className="size-16" src={`/img/providers/nodemailer.svg`} />
        <div className="text-sm text-center">Nodemailer</div>
      </RichTabs.Trigger>
      <RichTabs.Trigger
        value="postmark"
        orientation="vertical"
        className="!border border-neutral-200 dark:border-neutral-700 aria-selected:!bg-neutral-100 aria-selected:dark:!bg-neutral-950 dark:!bg-neutral-900 !bg-white !h-auto !w-auto !gap-2 !justify-start p-6 px-8 rounded-md outline-none transition-all duration-300 hover:bg-neutral-200 !font-normal"
      >
        <img className="size-16" src={`/img/providers/postmark.svg`} />
        <div className="text-sm text-center">Postmark</div>
      </RichTabs.Trigger>
            <RichTabs.Trigger
        value="loops"
        orientation="vertical"
        className="!border border-neutral-200 dark:border-neutral-700 aria-selected:!bg-neutral-100 aria-selected:dark:!bg-neutral-950 dark:!bg-neutral-900 !bg-white !h-auto !w-auto !gap-2 !justify-start p-6 px-8 rounded-md outline-none transition-all duration-300 hover:bg-neutral-200 !font-normal"
      >
        <img className="size-16" src={`/img/providers/loops.svg`} />
        <div className="text-sm text-center">Loops</div>
      </RichTabs.Trigger>
      <RichTabs.Trigger
        value="mailgun"
        orientation="vertical"
        className="!border border-neutral-200 dark:border-neutral-700 aria-selected:!bg-neutral-100 aria-selected:dark:!bg-neutral-950 dark:!bg-neutral-900 !bg-white !h-auto !w-auto !gap-2 !justify-start p-6 px-8 rounded-md outline-none transition-all duration-300 hover:bg-neutral-200 !font-normal"
      >
        <img className="size-16" src={`/img/providers/mailgun.svg`} />
        <div className="text-sm text-center">Mailgun</div>
      </RichTabs.Trigger>
    </RichTabs.List>
  <RichTabs.Content
    orientation="vertical"
    value="forwardemail"
    className="h-full !border-0 !w-full"
    tabIndex={-1}
  >

### Forward Email Setup

<Steps>

### Database Adapter

Please make sure you've [setup a database adapter](/getting-started/database), as mentioned earlier,
a database is required for passwordless login to work as verification tokens need to be stored.

### Setup Environment Variables

Auth.js will automatically pick up these if formatted like the example above.
You can [also use a different name for the environment variables](/guides/environment-variables#oauth-variables) if needed, but then you’ll need to pass them to the provider manually.

```bash filename=".env"
AUTH_FORWARDEMAIL_KEY=abc123
```

### Setup Provider

Let’s enable `ForwardEmail` as a sign in option in our Auth.js configuration. You’ll have to import the `ForwardEmail` provider from the package and pass it to the providers array we setup earlier in the Auth.js config file:

<Code>
<Code.Next>

```ts filename="./auth.ts"
import NextAuth from "next-auth"
import ForwardEmail from "next-auth/providers/forwardemail"

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [ForwardEmail],
})
```

</Code.Next>
<Code.Qwik>

```ts filename="/src/routes/plugin@auth.ts"
import { QwikAuth$ } from "@auth/qwik"
import ForwardEmail from "@auth/qwik/providers/forwardemail"

export const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$(
  () => ({
    providers: [ForwardEmail],
  })
)
```

</Code.Qwik>
<Code.Svelte>

```ts filename="./src/auth.ts"
import SvelteKitAuth from "@auth/sveltekit"
import ForwardEmail from "@auth/sveltekit/providers/forwardemail"

export const { handle, signIn, signOut } = SvelteKitAuth({
  providers: [ForwardEmail],
})
```

```ts filename="./src/hooks.server.ts"
export { handle } from "./auth"
```

</Code.Svelte>
</Code>

### Add Signin Button

Next, we can add a signin button somewhere in your application like the Navbar. This will send an email to the user containing the magic link to sign in.

<Code>
<Code.Next>

```tsx filename="./components/sign-in.tsx"
import { signIn } from "../../auth.ts"

export function SignIn() {
  return (
    <form
      action={async (formData) => {
        "use server"
        await signIn("forwardemail", formData)
      }}
    >
      <input type="text" name="email" placeholder="Email" />
      <button type="submit">Signin with Forward Email</button>
    </form>
  )
}
```

</Code.Next>
<Code.Qwik>

```ts filename="./components/sign-in.tsx"
import { component$ } from "@builder.io/qwik"
import { useSignIn } from "./plugin@auth"

export default component$(() => {
  const signInSig = useSignIn()

  return (
    <button
      onClick$={() => signInSig.submit({ redirectTo: "/" })}
    >
      SignIn
    </button>
  )
})
```

</Code.Qwik>
<Code.Svelte>

```html filename="src/routes/+page.svelte"
<script lang="ts">
  import { SignIn } from "@auth/sveltekit/components"
</script>

<div>
  <nav>
    <img src="/img/logo.svg" alt="Company Logo" />
    <SignIn provider="forwardemail" />
  </nav>
</div>
```

</Code.Svelte>
</Code>

### Signin

Start your application, once the user enters their Email and clicks on the signin button, they'll be redirected to a page that asks them to check their email. When they click on the link in their email, they will be signed in.

</Steps>

<Callout type="info">
  Check our [Customising magic links
  emails](/getting-started/providers/forwardemail#customization) to learn how to
  change the look and feel of the emails the user receives to sign in.
</Callout>

For more information on this provider go to the [Forward Email docs page](/getting-started/providers/forwardemail).

</RichTabs.Content>

<RichTabs.Content
  orientation="vertical"
  value="resend"
  className="h-full !border-0 !w-full"
  tabIndex={-1}
>

### Resend Setup

<Steps>

### Database Adapter

Please make sure you've [setup a database adapter](/getting-started/database), as mentioned earlier,
a database is required for passwordless login to work as verification tokens need to be stored.

### Setup Environment Variables

Auth.js will automatically pick up these if formatted like the example above.
You can [also use a different name for the environment variables](/guides/environment-variables#oauth-variables) if needed, but then you’ll need to pass them to the provider manually.

```bash filename=".env"
AUTH_RESEND_KEY=abc123
```

### Setup Provider

Let’s enable `Resend` as a sign in option in our Auth.js configuration. You’ll have to import the `Resend` provider from the package and pass it to the providers array we setup earlier in the Auth.js config file:

<Code>
<Code.Next>

```ts filename="./auth.ts"
import NextAuth from "next-auth"
import Resend from "next-auth/providers/resend"

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [Resend],
})
```

</Code.Next>
<Code.Qwik>

```ts filename="/src/routes/plugin@auth.ts"
import { QwikAuth$ } from "@auth/qwik"
import Resend from "@auth/qwik/providers/resend"

export const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$(
  () => ({
    providers: [Resend],
  })
)
```

</Code.Qwik>
<Code.Svelte>

```ts filename="./src/auth.ts"
import SvelteKitAuth from "@auth/sveltekit"
import Resend from "@auth/sveltekit/providers/resend"

export const { handle, signIn, signOut } = SvelteKitAuth({
  providers: [Resend],
})
```

```ts filename="./src/hooks.server.ts"
export { handle } from "./auth"
```

</Code.Svelte>
</Code>

### Add Signin Button

Next, we can add a signin button somewhere in your application like the Navbar. This will send an email to the user containing the magic link to sign in.

<Code>
<Code.Next>

```tsx filename="./components/sign-in.tsx"
import { signIn } from "../../auth.ts"

export function SignIn() {
  return (
    <form
      action={async (formData) => {
        "use server"
        await signIn("resend", formData)
      }}
    >
      <input type="text" name="email" placeholder="Email" />
      <button type="submit">Signin with Resend</button>
    </form>
  )
}
```

</Code.Next>
<Code.NextClient>

```tsx filename="./components/sign-in.tsx"
"use client"
import { signIn } from "next-auth/react"

export function SignIn() {
  const resendAction = (formData: FormData) => {
    signIn("resend", formData)
  }

  return (
    <form action={resendAction}>
      <label htmlFor="email-resend">
        Email
        <input type="email" id="email-resend" name="email" />
      </label>
      <input type="submit" value="Signin with Resend" />
    </form>
  )
}
```

</Code.NextClient>
<Code.Qwik>

```ts filename="./components/sign-in.tsx"
import { component$ } from "@builder.io/qwik"
import { useSignIn } from "./plugin@auth"

export default component$(() => {
  const signInSig = useSignIn()

  return (
    <button
      onClick$={() => signInSig.submit({ redirectTo: "/" })}
    >
      SignIn
    </button>
  )
})
```

</Code.Qwik>
<Code.Svelte>

```html filename="src/routes/+page.svelte"
<script lang="ts">
  import { SignIn } from "@auth/sveltekit/components"
</script>

<div>
  <nav>
    <img src="/img/logo.svg" alt="Company Logo" />
    <SignIn provider="resend" />
  </nav>
</div>
```

</Code.Svelte>
</Code>

### Signin

Start your application, once the user enters their Email and clicks on the signin button, they'll be redirected to a page that asks them to check their email. When they click on the link in their email, they will be signed in.

</Steps>

<Callout type="info">
  Check our [Customising magic links
  emails](/getting-started/providers/resend#customization) to learn how to
  change the look and feel of the emails the user receives to sign in.
</Callout>

For more information on this provider go to the [Resend docs page](/getting-started/providers/resend).

</RichTabs.Content>

<RichTabs.Content
  orientation="vertical"
  value="sendgrid"
  className="h-full !border-0 !w-full"
  tabIndex={-1}
>

### Sendgrid Setup

<Steps>

### Database Adapter

Please make sure you've [setup a database adapter](/getting-started/database), as mentioned earlier,
a database is required for passwordless login to work as verification tokens need to be stored.

### Setup Environment Variables

Auth.js will automatically pick up these if formatted like the example above.
You can [also use a different name for the environment variables](/guides/environment-variables#oauth-variables) if needed, but then you’ll need to pass them to the provider manually.

```bash filename=".env"
AUTH_SENDGRID_KEY=abc123
```

### Setup Provider

Let’s enable `Sendgrid` as a sign in option in our Auth.js configuration. You’ll have to import the `Sendgrid` provider from the package and pass it to the providers array we setup earlier in the Auth.js config file:

<Code>
<Code.Next>

```ts filename="./auth.ts"
import NextAuth from "next-auth"
import Sendgrid from "next-auth/providers/sendgrid"

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [Sendgrid],
})
```

</Code.Next>
<Code.Qwik>

```ts filename="/src/routes/plugin@auth.ts"
import { QwikAuth$ } from "@auth/qwik"
import Sendgrid from "@auth/qwik/providers/sendgrid"

export const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$(
  () => ({
    providers: [Sendgrid],
  })
)
```

</Code.Qwik>
<Code.Svelte>

```ts filename="./src/auth.ts"
import SvelteKitAuth from "@auth/sveltekit"
import Sendgrid from "@auth/sveltekit/providers/sendgrid"

export const { handle, signIn, signOut } = SvelteKitAuth({
  providers: [Sendgrid],
})
```

```ts filename="./src/hooks.server.ts"
export { handle } from "./auth"
```

</Code.Svelte>
</Code>

### Add Signin Button

Next, we can add a signin button somewhere in your application like the Navbar. This will send an email to the user containing the magic link to sign in.

<Code>
<Code.Next>

```tsx filename="./components/sign-in.tsx"
import { signIn } from "../../auth.ts"

export function SignIn() {
  return (
    <form
      action={async (formData) => {
        "use server"
        await signIn("sendgrid", formData)
      }}
    >
      <input type="text" name="email" placeholder="Email" />
      <button type="submit">Signin with Sendgrid</button>
    </form>
  )
}
```

</Code.Next>
<Code.NextClient>

```tsx filename="./components/sign-in.tsx"
"use client"
import { signIn } from "next-auth/react"

export function SignIn() {
  const sendgridAction = (formData: FormData) => {
    signIn("sendgrid", formData)
  }

  return (
    <form action={sendgridAction}>
      <label htmlFor="email-sendgrid">
        Email
        <input type="email" id="email-sendgrid" name="email" />
      </label>
      <input type="submit" value="Signin with Sendgrid" />
    </form>
  )
}
```

</Code.NextClient>
<Code.Qwik>

```ts filename="./components/sign-in.tsx"
import { component$ } from "@builder.io/qwik"
import { useSignIn } from "./plugin@auth"

export default component$(() => {
  const signInSig = useSignIn()

  return (
    <button
      onClick$={() => signInSig.submit({ redirectTo: "/" })}
    >
      SignIn
    </button>
  )
})
```

</Code.Qwik>
<Code.Svelte>

```html filename="src/routes/+page.svelte"
<script lang="ts">
  import { SignIn } from "@auth/sveltekit/components"
</script>

<div>
  <nav>
    <img src="/img/logo.svg" alt="Company Logo" />
    <SignIn provider="sendgrid" />
  </nav>
</div>
```

</Code.Svelte>
</Code>

### Signin

Start your application, once the user enters their Email and clicks on the signin button, they'll be redirected to a page that asks them to check their email. When they click on the link in their email, they will be signed in.

</Steps>

<Callout type="info">
  Check our [Customising magic links
  emails](/getting-started/providers/sendgrid#customization) to learn how to
  change the look and feel of the emails the user receives to sign in.
</Callout>

For more information on this provider go to the [Sendgrid docs page](/getting-started/providers/sendgrid).

</RichTabs.Content>

<RichTabs.Content
  orientation="vertical"
  value="nodemailer"
  className="h-full !border-0 !w-full"
  tabIndex={-1}
>

### Nodemailer Setup

<Steps>

### Install `nodemailer`

Auth.js does not include `nodemailer` as a dependency, so you'll need to install it yourself if you want to use the Nodemailer provider.

```sh npm2yarn
npm install nodemailer
```

You will need access to an SMTP server, ideally from one of [the services known to work with nodemailer](https://community.nodemailer.com/2-0-0-beta/setup-smtp/well-known-services/). Alternatively, Nodemailer does support [other transport mechanisms](https://nodemailer.com/transports/).

### Database Adapter

Please make sure you've [setup a database adapter](/getting-started/database), as mentioned earlier,
a database is required for magic link login to work as verification tokens need to be stored.

### SMTP Transport Configuration

There are two ways to configure the SMTP server connection: using a connection string or a configuration object.

<Tabs items={['Connection string', 'Configuration object']}>
  <Tabs.Tab>

```bash filename=".env"
EMAIL_SERVER=smtp://username:password@smtp.example.com:587
EMAIL_FROM=noreply@example.com
```

<Code>
<Code.Next>

```ts filename="./auth.ts"
import NextAuth from "next-auth"
import Nodemailer from "next-auth/providers/nodemailer"

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [
    Nodemailer({
      server: process.env.EMAIL_SERVER,
      from: process.env.EMAIL_FROM,
    }),
  ],
})
```

</Code.Next>
<Code.Qwik>

```ts filename="/src/routes/plugin@auth.ts"
import { QwikAuth$ } from "@auth/qwik"
import Nodemailer from "@auth/qwik/providers/nodemailer"

export const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$(
  () => ({
    providers: [
      Nodemailer({
        server: import.meta.env.EMAIL_SERVER,
        from: import.meta.env.EMAIL_FROM,
      }),
    ],
  })
)
```

</Code.Qwik>
<Code.Svelte>

```ts filename="./src/auth.ts"
import SvelteKitAuth from "@auth/sveltekit"
import Nodemailer from "@auth/sveltekit/providers/nodemailer"
import { env } from "$env/dynamic/private"

export const { handle, signIn, signOut } = SvelteKitAuth({
  providers: [
    Nodemailer({
      server: env.EMAIL_SERVER,
      from: env.EMAIL_FROM,
    }),
  ],
})
```

```ts filename="./src/hooks.server.ts"
export { handle } from "./auth"
```

</Code.Svelte>
</Code>

  </Tabs.Tab>
  <Tabs.Tab>

```bash filename=".env"
EMAIL_SERVER_USER=username
EMAIL_SERVER_PASSWORD=password
EMAIL_SERVER_HOST=smtp.example.com
EMAIL_SERVER_PORT=587
EMAIL_FROM=noreply@example.com
```

<Code>
<Code.Next>

```ts filename="./auth.ts"
import NextAuth from "next-auth"
import Nodemailer from "next-auth/providers/nodemailer"

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [
    Nodemailer({
      server: {
        host: process.env.EMAIL_SERVER_HOST,
        port: process.env.EMAIL_SERVER_PORT,
        auth: {
          user: process.env.EMAIL_SERVER_USER,
          pass: process.env.EMAIL_SERVER_PASSWORD,
        },
      },
      from: process.env.EMAIL_FROM,
    }),
  ],
})
```

</Code.Next>
<Code.Qwik>

```ts filename="/src/routes/plugin@auth.ts"
import { QwikAuth$ } from "@auth/qwik"
import Nodemailer from "@auth/qwik/providers/nodemailer"

export const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$(
  () => ({
    providers: [
      Nodemailer({
        server: {
          host: import.meta.env.EMAIL_SERVER_HOST,
          port: import.meta.env.EMAIL_SERVER_PORT,
          auth: {
            user: import.meta.env.EMAIL_SERVER_USER,
            pass: import.meta.env.EMAIL_SERVER_PASSWORD,
          },
        },
        from: import.meta.env.EMAIL_FROM,
      }),
    ],
  })
)
```

</Code.Qwik>
<Code.Svelte>

```ts filename="./src/auth.ts"
import SvelteKitAuth from "@auth/sveltekit"
import Nodemailer from "@auth/sveltekit/providers/nodemailer"
import { env } from "$env/dynamic/private"

export const { handle, signIn, signOut } = SvelteKitAuth({
  providers: [
    Nodemailer({
      server: {
        host: env.EMAIL_SERVER_HOST,
        port: env.EMAIL_SERVER_PORT,
        auth: {
          user: env.EMAIL_SERVER_USER,
          pass: env.EMAIL_SERVER_PASSWORD,
        },
      },
      from: env.EMAIL_FROM,
    }),
  ],
})
```

```ts filename="src/hooks.server.ts"
export { handle } from "./auth"
```

</Code.Svelte>
</Code>

  </Tabs.Tab>
</Tabs>

### Signin Button

Next, we can add a sign in button somewhere in your application like the Navbar. This will forward the user on to the Auth.js default signin page.

<Code>
<Code.Next>

```tsx filename="./components/sign-in.tsx"
import { signIn } from "../../auth.ts"

export function SignIn() {
  return (
    <form
      action={async () => {
        "use server"
        await signIn()
      }}
    >
      <button type="submit">Sign In</button>
    </form>
  )
}
```

</Code.Next>
<Code.Qwik>

```ts filename="./components/sign-in.tsx"
import { component$ } from "@builder.io/qwik"
import { useSignIn } from "./plugin@auth"

export default component$(() => {
  const signInSig = useSignIn()

  return (
    <button
      onClick$={() => signInSig.submit({ redirectTo: "/" })}
    >
      SignIn
    </button>
  )
})
```

</Code.Qwik>
<Code.Svelte>

```ts filename="src/routes/+page.svelte"
<script lang="ts">
  import { signIn } from '@auth/sveltekit/client'
</script>

<div>
  <nav>
    <img src="/img/logo.svg" alt="Company Logo" />
    <button on:click={signIn}>Signin</button>
  </nav>
</div>
```

</Code.Svelte>
</Code>

### Signin

Start your application, click on the sign in button we just added, and you should see Auth.js built-in sign in page with the option to sign in with your email:

<Screenshot src={MagicLink} alt="Screenshot of sign in page" />

Insert your email and click "Sign in with Email". You should receive an email from Auth.js, click on it and should be redirected to your application, landing already authenticated.

</Steps>

For more information on this provider go to the [Nodemailer docs page](/getting-started/providers/nodemailer).

</RichTabs.Content>
<RichTabs.Content
  orientation="vertical"
  value="postmark"
  className="h-full !border-0 !w-full"
  tabIndex={-1}
>

### Postmark Setup

<Steps>

### Database Adapter

Please make sure you've [setup a database adapter](/getting-started/database), as mentioned earlier,
a database is required for passwordless login to work as verification tokens need to be stored.

### Setup Environment Variables

Auth.js will automatically pick up these if formatted like the example above.
You can [also use a different name for the environment variables](/guides/environment-variables#oauth-variables) if needed, but then you’ll need to pass them to the provider manually.

```bash filename=".env"
AUTH_POSTMARK_KEY=abc123
```

### Setup Provider

Let’s enable `Postmark` as a sign in option in our Auth.js configuration. You’ll have to import the `Postmark` provider from the package and pass it to the providers array we setup earlier in the Auth.js config file:

<Code>
<Code.Next>

```ts filename="./auth.ts"
import NextAuth from "next-auth"
import Postmark from "next-auth/providers/postmark"

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [Postmark],
})
```

</Code.Next>
<Code.Qwik>

```ts filename="/src/routes/plugin@auth.ts"
import { QwikAuth$ } from "@auth/qwik"
import Postmark from "@auth/qwik/providers/postmark"

export const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$(
  () => ({
    providers: [Postmark],
  })
)
```

</Code.Qwik>
<Code.Svelte>

```ts filename="./src/auth.ts"
import SvelteKitAuth from "@auth/sveltekit"
import Postmark from "@auth/sveltekit/providers/postmark"

export const { handle, signIn, signOut } = SvelteKitAuth({
  providers: [Postmark],
})
```

```ts filename="./src/hooks.server.ts"
export { handle } from "./auth"
```

</Code.Svelte>
</Code>

### Add Signin Button

Next, we can add a signin button somewhere in your application like the Navbar. This will send an email to the user containing the magic link to sign in.

<Code>
<Code.Next>

```tsx filename="./components/sign-in.tsx"
import { signIn } from "../../auth.ts"

export function SignIn() {
  return (
    <form
      action={async (formData) => {
        "use server"
        await signIn("postmark", formData)
      }}
    >
      <input type="text" name="email" placeholder="Email" />
      <button type="submit">Signin with Postmark</button>
    </form>
  )
}
```

</Code.Next>
<Code.NextClient>

```tsx filename="./components/sign-in.tsx"
"use client"
import { signIn } from "next-auth/react"

export function SignIn() {
  const postmarkAction = (formData: FormData) => {
    signIn("postmark", formData)
  }

  return (
    <form action={postmarkAction}>
      <label htmlFor="email-postmark">
        Email
        <input type="email" id="email-postmark" name="email" />
      </label>
      <input type="submit" value="Signin with Postmark" />
    </form>
  )
}
```

</Code.NextClient>
<Code.Qwik>

```ts filename="./components/sign-in.tsx"
import { component$ } from "@builder.io/qwik"
import { useSignIn } from "./plugin@auth"

export default component$(() => {
  const signInSig = useSignIn()

  return (
    <button
      onClick$={() => signInSig.submit({ redirectTo: "/" })}
    >
      SignIn
    </button>
  )
})
```

</Code.Qwik>
<Code.Svelte>

```html filename="src/routes/+page.svelte"
<script lang="ts">
  import { SignIn } from "@auth/sveltekit/components"
</script>

<div>
  <nav>
    <img src="/img/logo.svg" alt="Company Logo" />
    <SignIn provider="postmark" />
  </nav>
</div>
```

</Code.Svelte>
</Code>

### Signin

Start your application, once the user enters their Email and clicks on the signin button, they'll be redirected to a page that asks them to check their email. When they click on the link in their email, they will be signed in.

</Steps>

<Callout type="info">
  Check our [Customising magic links
  emails](/getting-started/providers/postmark#customization) to learn how to
  change the look and feel of the emails the user receives to sign in.
</Callout>

For more information on this provider go to the [Postmark docs page](/getting-started/providers/postmark).

</RichTabs.Content>
<RichTabs.Content
orientation="vertical"
value="loops"
className="h-full !border-0 !w-full"
tabIndex={-1}>

### Loops Setup

<Steps>

### Database Adapter

Please make sure you've [setup a database adapter](/getting-started/database), as mentioned earlier,
a database is required for passwordless login to work as verification tokens need to be stored.

### Create your Transactional Email Template on Loops

Loops have provided a super handy [guide](https://loops.so/docs/transactional/guide) to help you get started with creating your transactional email template.
This provider only passes one data varaiable into the template, `url` which is the magic link to sign in. This is case sensitive, so make sure you use `url` in your template. <br/>
On the last page of Template creation, you'll need to copy the `TRANSACTIONAL ID`. If you skipped this step, don't worry, you can get this at any from the Template edit page.

### Create an API Key on Loops

You'll need to create an API key to authenticate with Loops. This key should be kept secret and not shared with anyone.
You can Generate a key by going to the [API Settings Page](https://app.loops.so/settings?page=api) and clicking Generate.
You should name the key something that makes sense to you, like "Auth.js".

### Setup Environment Variables

To implement Loops, you need to set up the following environment variables. You should have these from the previous steps.

```bash filename=".env"
AUTH_LOOPS_KEY=abc123
AUTH_LOOPS_TRANSACTIONAL_ID=def456
```

### Setup Provider

Let's enable `Loops` as a sign-in option for our Auth.js configuration. You'll have to import the `Loops` provider from the package and pass it to the providers array we set up earlier in the Auth.js config file:

<Code>
<Code.Next>

```ts filename="./auth.ts"
import NextAuth from "next-auth"
import Loops from "next-auth/providers/loops"

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [
    Loops({
      apiKey: process.env.AUTH_LOOPS_KEY,
      transactionalId: process.env.AUTH_LOOPS_TRANSACTIONAL_ID,
    }),
  ],
})
```

</Code.Next>
<Code.Svelte>

```ts filename="./src/auth.ts"
import SvelteKitAuth from "@auth/sveltekit"
import Loops from "@auth/sveltekit/providers/loops"
import {
  AUTH_LOOPS_KEY,
  AUTH_LOOPS_TRANSACTIONAL_ID,
} from "$env/static/private"

export const { handle, signIn, signOut } = SvelteKitAuth({
  providers: [
    Loops({
      apiKey: AUTH_LOOPS_KEY,
      transactionalId: AUTH_LOOPS_TRANSACTIONAL_ID,
    }),
  ],
})
```

```ts filename="./src/hooks.server.ts"
export { handle } from "./auth"
```

</Code.Svelte>
</Code>

### Add Signin Button

Next, we add a signin button somewhere in your application like the Navbar. This will send an email to the user containing the magic link to sign in.

<Code>
<Code.Next>

```tsx filename="./components/sign-in.tsx"
import { signIn } from "../../auth.ts"

export function SignIn() {
  return (
    <form
      action={async (formData) => {
        "use server"
        await signIn("loops", formData)
      }}
    >
      <input type="text" name="email" placeholder="Email" />
      <button type="submit">Sign in with Loops</button>
    </form>
  )
}
```

</Code.Next>
<Code.Svelte>

```ts filename="src/routes/+page.svelte"

<script lang="ts">
  import { SignIn } from "@auth/sveltekit/components"
</script>

<div>
  <nav>
    <img src="/img/logo.svg" alt="Company Logo" />
    <SignIn provider="loops"/>
  </nav>
</div>

```

</Code.Svelte>
</Code>

### Signin

Start your application, click on the signin button we just added, and you should see Auth.js built-in sign in page with the option to sign in with your email.
A user can enter their email, click "Sign in with Loops", and receive their beautifully formatted signin email.
Clicking on the link in the email will redirect the user to your application, landing already authenticated!

</Steps>
</RichTabs.Content>
<RichTabs.Content
  orientation="vertical"
  value="mailgun"
  className="h-full !border-0 !w-full"
  tabIndex={-1}
>

### Mailgun Setup

<Steps>

### Database Adapter

Please make sure you've [setup a database adapter](/getting-started/database), as mentioned earlier,
a database is required for passwordless login to work as verification tokens need to be stored.

### Setup Environment Variables

Auth.js will automatically pick up these if formatted like the example above.
You can [also use a different name for the environment variables](/guides/environment-variables#oauth-variables) if needed, but then you’ll need to pass them to the provider manually.

```bash filename=".env"
AUTH_MAILGUN_KEY=abc123
```

### Setup Provider

Let’s enable `Mailgun` as a sign in option in our Auth.js configuration.
You’ll have to import the `Mailgun` provider from the package and pass it to the providers array we setup earlier in the Auth.js config file:

<Code>
<Code.Next>

```ts filename="./auth.ts"
import NextAuth from "next-auth"
import Mailgun from "next-auth/providers/mailgun"

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [Mailgun],
})
```

</Code.Next>
<Code.Qwik>
  
```ts filename="/src/routes/plugin@auth.ts"
import { QwikAuth$ } from "@auth/qwik"
import Mailgun from "@auth/qwik/providers/mailgun"

export const { onRequest, useSession, useSignIn, useSignOut } = QwikAuth$(
  () => ({
    providers: [Mailgun],
  })
)
```

</Code.Qwik>
<Code.Svelte>

```ts filename="./src/auth.ts"
import SvelteKitAuth from "@auth/sveltekit"
import Mailgun from "@auth/sveltekit/providers/mailgun"

export const { handle, signIn, signOut } = SvelteKitAuth({
  providers: [Mailgun],
})
```

```ts filename="./src/hooks.server.ts"
export { handle } from "./auth"
```

</Code.Svelte>
</Code>

### Add Signin Button

Next, we can add a signin button somewhere in your application like the Navbar. This will send an email to the user containing the magic link to sign in.

<Code>
<Code.Next>

```tsx filename="./components/sign-in.tsx"
import { signIn } from "../../auth.ts"

export function SignIn() {
  return (
    <form
      action={async (formData) => {
        "use server"
        await signIn("mailgun", formData)
      }}
    >
      <input type="text" name="email" placeholder="Email" />
      <button type="submit">Signin with Mailgun</button>
    </form>
  )
}
```

</Code.Next>
<Code.Qwik>

```ts filename="./components/sign-in.tsx"
import { component$ } from "@builder.io/qwik"
import { useSignIn } from "./plugin@auth"

export default component$(() => {
  const signInSig = useSignIn()

  return (
    <button
      onClick$={() => signInSig.submit({ redirectTo: "/" })}
    >
      SignIn
    </button>
  )
})
```

</Code.Qwik>
<Code.Svelte>

```html filename="src/routes/+page.svelte"
<script lang="ts">
  import { SignIn } from "@auth/sveltekit/components"
</script>

<div>
  <nav>
    <img src="/img/logo.svg" alt="Company Logo" />
    <SignIn provider="mailgun" />
  </nav>
</div>
```

</Code.Svelte>
</Code>

### Signin

Start your application, once the user enters their Email and clicks on the signin button, they'll be redirected to a page that asks them to check their email. When they click on the link in their email, they will be signed in.

</Steps>

<Callout type="info">
  Check our [Customising magic links
  emails](/getting-started/providers/mailgun#customization) to learn how to
  change the look and feel of the emails the user receives to sign in.
</Callout>

For more information on this provider go to the [Mailgun docs page](/getting-started/providers/mailgun).

</RichTabs.Content>
</RichTabs>
</div>
